package com.jrx.anytxn.reporting.job.xib.step;

import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import com.jrx.anytxn.reporting.entity.LoanAcctVo;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.AmLoanAccountInfo;
import com.jrx.anytxn.transaction.entity.AmRepaymentPlanInfo;
import com.jrx.anytxn.transaction.entity.TlPaymentAllocationLog;
import com.jrx.anytxn.transaction.mapper.ext.ExtAmRepaymentPlanInfoMapper;
import com.jrx.anytxn.transaction.mapper.ext.ExtTlPaymentAllocationLogMapper;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @description: 计算客户日终余额Processor
 * @author: liuzb
 * @date: 2024/5/23 14:29
 */
@Service
public class CustBalHandleProcessor implements ItemProcessor<LoanAcctVo, AmLoanAccountInfo> {

    @Resource
    private ExtAmRepaymentPlanInfoMapper extAmRepaymentPlanInfoMapper;

    @Resource
    private IOrganizationTableService organizationTableService;

    @Resource
    private ExtTlPaymentAllocationLogMapper paymentAllocationLogMapper;

    private static final Logger logger = LoggerFactory.getLogger(CustBalHandleProcessor.class);

    @Override
    public AmLoanAccountInfo process(LoanAcctVo item) throws Exception {
        AmLoanAccountInfo updateLoanAcc = null;
        try {
            if (Objects.nonNull(item)) {
                logger.info("CustBalHandleProcessor:客户:{},借据编号:{}", item.getCurrBalance(), item.getLoanId());
                //正常本金 所有已抛未还本金 （不包含逾期本金）
                BigDecimal principal = BigDecimal.ZERO;
                //逾期本金
                BigDecimal ovdrPrincipal = BigDecimal.ZERO;
                //获取当期业务时间
                PrOrganizationTable org = organizationTableService.findByOrId(TransBizConstant.DEFAULT_ORG_ID, item.getTenantId());
                Date busiDate = org.getToday();
                // 找还款分配表-在切日后，供数前的余额数据需要还原
                List<TlPaymentAllocationLog> tlPaymentAllocationLogs = paymentAllocationLogMapper.selectByLoanIdDesc(item.getLoanId(), item.getCustomerId(), item.getTenantId(),
                        TransBizConstant.PAYMENT_ALLOCATION_TYPE_09);
                principal = principal.add(tlPaymentAllocationLogs.stream()
                        .filter(log -> log.getPostingDate().compareTo(busiDate) > 0)
                        .filter(log -> Arrays.asList(TransBizConstant.TXN_CODE_INST_PYMT, TransBizConstant.TXN_CODE_STAGING_PRINCIPAL, TransBizConstant.TXN_CODE_REFUND).contains(log.getTxnCode()))
                        .map(TlPaymentAllocationLog::getPostingAmount)
                        .reduce(BigDecimal.ZERO, BigDecimal::add));
                if (TransBizConstant.ACCOUNT_STATUS_0.equals(item.getAccountStatus()) || TransBizConstant.ACCOUNT_STATUS_1.equals(item.getAccountStatus())) {
                    principal = principal.add(item.getRemainPrincipal());
                } else if (TransBizConstant.ACCOUNT_STATUS_2.equals(item.getAccountStatus())) {
                    Predicate<AmRepaymentPlanInfo> status = acct ->
                            TransBizConstant.LOAN_PLAN_STATUS_0.equals(acct.getPlanStatus())
                                    || TransBizConstant.LOAN_PLAN_STATUS_1.equals(acct.getPlanStatus())
                                    || TransBizConstant.LOAN_PLAN_STATUS_2.equals(acct.getPlanStatus());
                    List<AmRepaymentPlanInfo> dealPlanList = extAmRepaymentPlanInfoMapper.selectRepaymentPlanInfoListByLoanIdAndStatus(item.getLoanId(),
                            new String[]{TransBizConstant.LOAN_PLAN_STATUS_0, TransBizConstant.LOAN_PLAN_STATUS_1, TransBizConstant.LOAN_PLAN_STATUS_2},
                            item.getCustomerId(), item.getTenantId());
                    //逾期
                    List<AmRepaymentPlanInfo> planInfoList = dealPlanList.stream()
                            .filter(status)
                            .filter(p -> item.getLoanId().equalsIgnoreCase(p.getLoanId()))
                            .collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(planInfoList)) {
                        //逾期部分还款计划
                        for (AmRepaymentPlanInfo plan : planInfoList) {
                            if (TransBizConstant.LOAN_PLAN_STATUS_2.equals(plan.getPlanStatus())) {
                                //当前本金 - 已还本金
                                BigDecimal overPrincipal = plan.getPrincipalAmount().subtract(plan.getRepayPrincipal());
                                ovdrPrincipal = ovdrPrincipal.add(overPrincipal);
                            } else {
                                BigDecimal prin = plan.getPrincipalAmount().subtract(plan.getRepayPrincipal());
                                principal = principal.add(prin);
                            }
                        }
                    }
                }
                updateLoanAcc = new AmLoanAccountInfo();
                updateLoanAcc.setId(item.getId());
                updateLoanAcc.setCustomerId(item.getCustomerId());
                updateLoanAcc.setTenantId(item.getTenantId());
                // 设置正常本金余额
                updateLoanAcc.setNormalPrinBal(principal);
                // 设置逾期本金余额
                updateLoanAcc.setOvduePrinBal(ovdrPrincipal);
                return updateLoanAcc;
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("CustBalHandleProcessor出错了：{}", e.getMessage());
        }
        return updateLoanAcc;
    }
}
